package ch.ethz.inf.shop.model.simpleDatabase;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * A tuple in our database. A tuple consists of a schema (describing the names
 * of the columns) and values. A tuple is created and modified by operators.
 * 
 * You can use String to store the values. In case you need a specific type, you
 * can use the additional getType methods.
 */
public class Tuple {
	public static final SimpleDateFormat HOUR_MINUTE_SECOND_FORMAT = new SimpleDateFormat("HH:mm:ss");
	public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private final TupleSchema schema;
	private final List<String> values;

	public List<String> getValues() {
		return values;
	}

	public Tuple(final TupleSchema schema, final String[] values) {
		this.schema = schema;
		this.values = new ArrayList<String>();
		for (String string : values) {
			this.values.add(string);
		}
	}

	public Tuple(final TupleSchema schema, final List<String> values) {
		this.schema = schema;
		this.values = values;
	}

	public final TupleSchema getSchema() {
		return this.schema;
	}

	private final String get(final int index) {
		return this.values.get(index);
	}

	public final int getInt(final int index) {
		return "".equals(this.values.get(index)) ? 0 : Integer.parseInt(this.values.get(index));
	}

	private BigDecimal getBigDecimal(int index) {
		return "".equals(this.values.get(index)) ? new BigDecimal(0) : new BigDecimal(this.values.get(index));
	}

	public final String getString(final int index) {
		return this.values.get(index);
	}

	public final Date getTime(final int index) throws ParseException {
		return HOUR_MINUTE_SECOND_FORMAT.parse(this.values.get(index));
	}

	public final Date getDate(final int index) throws ParseException {
		return DATE_FORMAT.parse(this.values.get(index));
	}

	// TODO
	// You may add other custom type getters here
	// i.e. Date, Time

	@Override
	public final String toString() {
		final StringBuilder buf = new StringBuilder();
		for (int i = 0; i < values.size(); i++) {
			buf.append(values.get(i));
			if (i < values.size() - 1) {
				buf.append(",");
			}
		}
		return buf.toString();
	}

	public int getInt(String column) {
		int index = schema.getIndex(column);
		return index == -1 ? -1 : this.getInt(index);
	}

	public String getString(String column) {
		int index = schema.getIndex(column);
		return index == -1 ? "" : this.getString(this.schema.getIndex(column));
	}

	public Date getDate(String column) throws ParseException {
		int index = schema.getIndex(column);
		return index == -1 ? null : this.getDate(this.schema.getIndex(column));
	}

	public BigDecimal getBigDecimal(String column) {
		int index = schema.getIndex(column);
		return index == -1 ? null : this.getBigDecimal(this.schema.getIndex(column));
	}

	public Date getTime(String column) throws ParseException {
		int index = schema.getIndex(column);
		return index == -1 ? null : this.getTime(this.schema.getIndex(column));
	}

	public Object get(String column) {
		int index = schema.getIndex(column);
		return index == -1 ? null : this.get(this.schema.getIndex(column));
	}

	public void setInt(String colName, int val) {
		int index = schema.getIndex(colName);
		if (index != -1) {
			this.values.set(this.schema.getIndex(colName), "" + val);
		}
	}

	public void setBigDecimal(String colName, BigDecimal val) {
		int index = schema.getIndex(colName);
		if (index != -1)
			this.values.set(this.schema.getIndex(colName), val.toString());
	}

}
